AddCSLuaFile( "cl_init.lua" );
AddCSLuaFile( "shared.lua" );
AddCSLuaFile( "block.lua" );

include('shared.lua');

function ENT:Initialize()
	self.Entity:SetModel("models/props_lab/blastdoor001c.mdl");
	self.Entity:PhysicsInit( SOLID_VPHYSICS );
	self.Entity:SetMoveType( MOVETYPE_VPHYSICS );
	self.Entity:SetSolid( SOLID_VPHYSICS );
	
	local phys = self.Entity:GetPhysicsObject();
	
	if(phys:IsValid()) then
		phys:Wake();
		phys:EnableMotion( false );
	end
	
	self.block = {};
	self.blockName = "";
	self.Entity:SetNetworkedInt("blockHealth", 0);
	self:SetNetworkedBool("isHack", false);
	self.hackTime = 0;
	self.hackTimeOverride = 0;
end 

function ENT:GetTeam()
	return self.block.Team;
end

function ENT:SetBlock(bhb, t)
	self.blockName = bhb;
	self.block = deepcopy(self.Blocks[bhb]);
	self.block.SENT = self;
	if(self.block.Model != nil) then
		self.Entity:SetModel(self.block.Model);
		self.Entity:PhysicsInit(SOLID_VPHYSICS);
		self.Entity:SetMoveType(MOVETYPE_VPHYSICS);
		self.Entity:SetSolid(SOLID_VPHYSICS);
		
		local phy = self.Entity:GetPhysicsObject();
		if(phy:IsValid()) then
			phy:Wake();
		end
	end
	self.block.Team = t;
	self.block:Init();
	self.Entity:SetNetworkedInt("blockHealth", self.block.Health);
end

function ENT:UpdateClient( ply )	umsg.Start("SendClientBlock", ply);
		umsg.Long(self.Entity:EntIndex());
		umsg.String(self.blockName);
	umsg.End();
	
	local h = self.Entity:GetNetworkedInt("blockHealth");
	self.Entity:SetNetworkedInt("blockHealth", 0);
	self.Entity:SetNetworkedInt("blockHealth", h);
	
	umsg.Start("SendClientTeam", ply);
		umsg.Long(self.Entity:EntIndex());
		umsg.Long(self.block.Team);
	umsg.End();
end

function ENT:Use(activator, caller)
	if(!activator:IsPlayer()) then return; end;
	if(activator:Team() != self.block.Team) then return; end
	local id = activator:UserID();
	umsg.Start("OpenClientPanel", activator);
		umsg.Long(self:EntIndex());
	umsg.End();
end 

function ENT:BuildCommand(ply)
	self.Entity:SetNetworkedInt("show_hack", ply:UserID());
end

function ENT:ClientMessage(cmd, a)
	if(cmd == "update") then
		self:UpdateClient();
	elseif(cmd == "set") then
		local id = tostring(a[3]);
		local val = tonumber(a[4]);
		self.Entity:SetNetworkedInt(id, val);
	end
end

function ENT:StartTouch(ent)
	self.block:StartTouch(ent);
end

function ENT:EndTouch(ent)
	self.block:EndTouch();
end

function ENT:OnRemove()
	if(self.block.PlayerSpawn) then hook.Call("IncrementBlocks", nil, self.block.Team, -1); end
end

function ENT:OnTakeDamage(dmg)
	local att = dmg:GetAttacker();
	if(!att:IsPlayer()) then return; end
	if(att:Team() == self.block.Team) then return; end
	local myHealth = self.Entity:GetNetworkedInt("blockHealth");
	myHealth = myHealth - dmg:GetDamage();
	self.Entity:SetNetworkedInt("blockHealth", myHealth);
	
	local ratio = myHealth / self.block.Health;
	if(ratio < 0.1) then constraint.RemoveAll(self.Entity); end
	if(myHealth <= 0) then
		//Create our explosion effect
		local effData = EffectData();
		effData:SetStart(self:GetPos());
		effData:SetOrigin(self:GetPos());
		effData:SetScale(1);
		util.Effect( "Explosion", effData);
		self.block:Removed();
		self:Remove();
	end
end

function BHServer(p,c,a)
	local e = ents.GetByIndex(tonumber(a[2]));
	local func = a[1];
	e:ClientMessage(func, a);
end
concommand.Add("bhserver", BHServer);

function ENT:Think()
	self.block:Think();
	local isHack = self.Entity:GetNetworkedBool("isHack");
	if(isHack) then
		local hackLeft = CurTime() - self.hackTime;
		local h = 0;
		if(self.hackTimeOverride != 0) then h = self.hackTimeOverride;
		else h = self.block.HackDuration;
		end
		if(hackLeft >= h) then 
			hackTimeOverride = 0;
			self:SetNetworkedBool("isHack", false);
			self.block:EndHack();
		end
	end
end

function ENT:ForceHackEnd()
	if(self.Entity:GetNetworkedBool("isHack")) then
		self.hackTimeOverride = 0;
		self:SetNetworkedBool("isHack", false);
		self.block:EndHack();
	end
end

function ENT:PhysicsCollide(data, phys)
	self.block:Collide(data, phys);
end

function ENT:Touch(ent)
	self.block:Touch(ent);
end

function ENT:Hack(ply, time)
	self.block:Hack(ply);
	if(time) then self.hackTimeOverride = time; end
	self:SetNetworkedBool("isHack", true);
	self.hackTime = CurTime();
	self:RefreshHackEffect();
end

function ENT:RefreshHackEffect()
	if(!self.Entity:GetNetworkedBool("isHack")) then return; end
	local effectdata = EffectData();
	effectdata:SetEntity(self);
	util.Effect("propspawn", effectdata, true, true);
	/*local this = self;
	timer.Create("bh_hackeffect", 3, 1, function() this:RefreshHackEffect(); end);*/
end

function ENT:GetHackTime()
	return self.block.HackTime;
end